'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _keys = require('babel-runtime/core-js/object/keys');

var _keys2 = _interopRequireDefault(_keys);

var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');

var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);

exports.getImportedOrRequiredModules = getImportedOrRequiredModules;
exports.normalizeModuleName = normalizeModuleName;
exports.analizeImportDeclarationAST = analizeImportDeclarationAST;
exports.analizeCallExpressionOfVariableDeclaration = analizeCallExpressionOfVariableDeclaration;
exports.getGitConfig = getGitConfig;
exports.getDepsInfo = getDepsInfo;
exports.getMacAddress = getMacAddress;

var _debug = require('debug');

var _debug2 = _interopRequireDefault(_debug);

var _gracefulFs = require('graceful-fs');

var _gracefulFs2 = _interopRequireDefault(_gracefulFs);

var _os = require('os');

var _os2 = _interopRequireDefault(_os);

var _path = require('path');

var _path2 = _interopRequireDefault(_path);

var _ini = require('ini');

var _ini2 = _interopRequireDefault(_ini);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var debug = (0, _debug2.default)('next:collect');

/**
 * 分析 import/require 语句
 * @param ast
 * @returns {*}
 */
/**
 * Created at 16/7/11.
 * @Author Ling.
 * @Email i@zeroling.com
 */
function getImportedOrRequiredModules(ast) {
  var handlerMap = {
    ImportDeclaration: analizeImportDeclarationAST,
    VariableDeclaration: analizeCallExpressionOfVariableDeclaration
  };

  return ast.program.body.reduce(function (ret, currentBody) {
    var handler = handlerMap[currentBody.type];
    var analized = handler && handler(currentBody);
    return analized ? [].concat((0, _toConsumableArray3.default)(ret), (0, _toConsumableArray3.default)(analized)) : ret;
  }, []);
}

/**
 * 得到原始包名称
 * @param rawModuleLiteral
 * @returns string
 */
function normalizeModuleName(rawModuleLiteral) {
  if (rawModuleLiteral[0] === '.') {
    // 暂时不处理本地的引用
    return '';
  }

  // normalize module name
  if (rawModuleLiteral[0] === '@') {
    // scoped module like '@ali/ice'
    return (rawModuleLiteral.match(/(@\w*\/[^\/]*)/) || [])[0];
  } else {
    return (rawModuleLiteral.match(/[^\/]*/) || [])[0];
  }
}

/**
 * 分析 import 语句
 * @param importDeclaration
 * @returns {{importedValue: Array, fromLiteral: *, fromModule}}
 */
function analizeImportDeclarationAST(importDeclaration) {

  var specifiers = importDeclaration.specifiers || [];
  var fromLiteral = importDeclaration.source.value;
  var fromModule = normalizeModuleName(fromLiteral);

  if ('' === fromModule) {
    // 不处理业务模块
    return null;
  }

  var length = specifiers.length;
  var objResult = {};

  specifiers.forEach(function (specifier, index) {
    var specifierType = specifier.type;

    if (!specifierType) return;

    if (specifierType === 'ImportDefaultSpecifier') {
      objResult['ImportDefaultSpecifier'] = {
        importedValue: specifiers[0]['local']['name'],
        fromLiteral: fromLiteral,
        fromModule: fromModule
      };
    } else if (specifierType === 'ImportSpecifier') {
      if (!objResult['ImportSpecifier']) {
        objResult['ImportSpecifier'] = {
          importedValue: [specifier['imported']['name']],
          fromLiteral: fromLiteral,
          fromModule: fromModule
        };
        return;
      }

      objResult['ImportSpecifier'].importedValue.push(specifier['imported']['name']);
    }
  });

  var result = (0, _keys2.default)(objResult).map(function (item, index) {
    return objResult[item];
  });

  return result;
}

/**
 * 处理 const Button = require('@ali/ice/lib/button') 这种情况
 * @param variableDeclaration
 * @returns {{importedValue: Array, fromLiteral: string, fromModule: string}}
 */
function analizeCallExpressionOfVariableDeclaration(variableDeclaration) {
  var result = [];
  var declarations = variableDeclaration.declarations;
  var declaration = variableDeclaration && variableDeclaration.declarations && variableDeclaration.declarations[0];

  var length = declarations.length;

  if ( // 判断处理条件
  declaration && declaration.type === 'VariableDeclarator' && // 1. 是变量声明语句
  declaration.init && declaration.init.type === 'CallExpression' && declaration.init.callee.name === 'require' // 2. 是由 require 初始化的
  ) {
      var fromLiteral = declaration.init['arguments'][0]['value'];
      var fromModule = normalizeModuleName(fromLiteral);
      if ('' === fromModule) {
        // 不处理业务模块
        return null;
      }

      var identifier = declaration.id;
      var _length = identifier.properties;
      if (identifier && identifier.type === 'Identifier') {
        result.push({
          importedValue: identifier.name,
          fromLiteral: fromLiteral,
          fromModule: fromModule
        });
      } else if (identifier && identifier.type === 'ObjectPattern') {
        result.push({
          importedValue: identifier.properties.map(function (property) {
            return property.value.name;
          }),
          fromLiteral: fromLiteral,
          fromModule: fromModule
        });
      }

      debug(result);

      return result;
    }
}

/**
 * 获取 git 信息：包括本次提交者花名，仓库地址等
 */
function getGitConfig(dir) {
  var homedir = _os2.default.homedir();
  var gitGlobalPath = _path2.default.join(homedir, '.gitconfig');
  var gitGlobalConfig = {};
  var gitLocalConfig = {};

  if (_gracefulFs2.default.existsSync(gitGlobalPath)) {
    try {
      gitGlobalConfig = _ini2.default.parse(_gracefulFs2.default.readFileSync(gitGlobalPath, 'utf-8'));
    } catch (err) {
      debug('git config 错误：', err.message);
      gitGlobalConfig = {};
    }
  }

  var gitLocalPath = _path2.default.join(dir, '.git/config');
  if (_gracefulFs2.default.existsSync(gitLocalPath)) {
    try {
      gitLocalConfig = _ini2.default.parse(_gracefulFs2.default.readFileSync(gitLocalPath, 'utf-8'));
    } catch (err) {
      debug('git config 错误：', err.message);
      gitLocalConfig = {};
    }
  }

  var url = (gitLocalConfig['remote "origin"'] || {})['url'] || '';
  var repoName = '';
  if (url) {
    repoName = (url.match(/.*\.com[:\/](.*\/.*)\.git/) || [,])[1];
  }

  var userName = (gitLocalConfig.user || gitGlobalConfig.user || {})['name'];
  return {
    url: url,
    repoName: repoName,
    userName: userName
  };
}

/**
 * 获取项目的依赖信息
 */
function getDepsInfo(rootDir, pkg) {
  var dependencies = pkg['dependencies'] || {};
  var modules = (0, _keys2.default)(dependencies).map(function (module) {
    var pkgPath = _path2.default.join(rootDir, 'node_modules', module, 'package.json');
    try {
      var modulePkg = JSON.parse(_gracefulFs2.default.readFileSync(pkgPath, 'utf-8'));
      return {
        module: modulePkg['name'],
        pkgVersion: dependencies[module],
        version: modulePkg['version']
      };
    } catch (err) {
      debug('\u83B7\u53D6 ' + module + ' pkg.json \u51FA\u9519', err.message);
      return {
        module: module,
        pkgVersion: dependencies[module],
        version: 'not installed'
      };
    }
  });

  return modules;
}

/**
 * 获取目标主机的mac地址
 */
function getMacAddress() {
  var ifaces = require('os').networkInterfaces();

  for (var dev in ifaces) {
    var iface = ifaces[dev];
    for (var i = 0; i < iface.length; i++) {
      var alias = iface[i];
      if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {
        return alias.mac;
      }
    }
  }
}